﻿#include "privatechat.h"
#include "ui_privatechat.h"
#include "mytextedit.h"
#include "login.h"
#include "mypdu.h"
#include "filetrans.h"
#include "expressionui.h"
#include <QWidget>
#include <QScrollBar>
#include <QProcess>
#include "videocall.h"

QString filepath;
QString recvobjname;

PrivateChat::PrivateChat(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PrivateChat)
{

    setWindowFlags(Qt::FramelessWindowHint);//将窗口标题去掉
    ui->setupUi(this);
    setWindowTitle(Widget::getInstance().getName());
    connect(&m_timer,&QTimer::timeout,this,&PrivateChat::ColoringListItem);
    connect(&m_filetimer,&QTimer::timeout,this,[=](){
            m_filetimer.stop();
            SendFileData();
    });
    connect(this,&PrivateChat::FileTransSTart,this,&PrivateChat::OnFileTransSTart);
    m_timer.start(100);
    m_prevItem = nullptr;
    ui->input_edit->setParent(this);
    ui->input_edit->move(230,460);
    ui->input_edit->resize(770,130);
    ui->input_edit->show();
    ui->widget_3->setParent(this);
    ui->widget_3->move(220,40);
    ui->widget_3->resize(790,340);
    ui->widget_3->show();
    ui->recv_name->setStyleSheet("color:white;font: 75 12pt \"微软雅黑\";");

    ui->widget_4->setParent(this);
    ui->widget_4->move(0,0);
    ui->widget_4->resize(1000,40);
    ui->widget_4->setStyleSheet("background-color:black;");

    ui->widget_5->setParent(this);
    ui->widget_5->move(0,40);
    ui->widget_5->resize(220,620);
    ui->widget_5->setStyleSheet("background-color:black;");

    ui->label->setParent(this);
    ui->label->move(230,380);
    ui->label->resize(770,5);
    ui->friend_list->setStyleSheet("color:white;");

    ui->widget->setStyleSheet("background-color:rgb(180,180,180);");
    ui->widget->setParent(this);
    ui->widget->move(230,410);
    ui->widget->resize(770,50);
}

PrivateChat::~PrivateChat()
{
    delete ui;
}

PrivateChat &PrivateChat::getInstance()
{
    static PrivateChat instance;
    return instance;
}

void PrivateChat::setObjName(QString name)
{
    ui->recv_name->setText(name);
}

QString PrivateChat::getObjName()
{
    return ui->recv_name->text();
}

QString PrivateChat::getSelfName()
{
    return Widget::getInstance().getName();
}

void PrivateChat::insertFrienNameToList(QString name)
{
    QList<QListWidgetItem*> list = ui->friend_list->findItems(name,Qt::MatchContains);
    if(list.size()==0)
        ui->friend_list->addItem(name);
}

void PrivateChat::restorChatRecord(QString name)
{
    QStringList list = name.split("&");
    list[2] = list[2].replace("わ","");
    QWidget* widget = new QWidget;
    widget->setStyleSheet("background:rgba(0,0,0,0);");
    widget->setMaximumSize(700,80);
    QHBoxLayout *horLayout = new QHBoxLayout();//水平布局
    horLayout->setContentsMargins(0,0,0,0);
    horLayout->setSpacing(0);
    QLabel * label = new QLabel(list[1]);
    label->setAlignment(Qt::AlignCenter);
    horLayout->addWidget(label);
    widget->setLayout(horLayout);
    ui->verticalLayout->addWidget(widget);
    if(list[0]==Widget::getInstance().getName())
        ui->verticalLayout->addWidget(CreateWidgetL_R(0,list[0],list[2]));
    else
        ui->verticalLayout->addWidget(CreateWidgetL_R(1,list[0],list[2]));
}

void PrivateChat::SendFileData()
{
    qint64 r = 0;
    char buff[1024];
    while(1)
    {
        r = m_file.read(buff,1024);//从文件中读取
        if(r > 0)
        {//读到了
            r = Widget::getInstance().getFileSocket().write(buff,r);//发给接收端
            if(r > 0)
            {
                sendsize += r;//累加已经发送的文件大小
                FileTrans::getInstance().setProgress(sendsize);
                if(sendsize >= filesize) break;
            }
            else
            {
                break;
            }
        }
        else
        {

            break;
        }
    }
    //到这表示文件已经读完
    FileTrans::getInstance().setLableContent(2,filename);
}

void PrivateChat::setSelectFriend(QString name)
{
    QList<QListWidgetItem*> list = ui->friend_list->findItems(name,Qt::MatchContains);
    if(!list.empty())
    {
        ui->friend_list->setCurrentItem(list[0]);
    }
}

QString PrivateChat::getFileName()
{
    return filename;
}

QPixmap PrivateChat::PixmapToRound(const QPixmap &src, const int &radius)
{
    if (src.isNull()) {
        return QPixmap();
    }
    QSize size(2*radius, 2*radius);
    //掩码图（黑白色）
    QBitmap mask(size);
    QPainter painter(&mask);
    //Antialiasing：反走样（抗锯齿）
    painter.setRenderHint(QPainter::Antialiasing);
    //SmoothPixmapTransform：用来在对图片进行缩放时启用线性插值算法而不是最邻近算法
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    //填充矩形
    painter.fillRect(0, 0, size.width(), size.height(), Qt::white);
    //画刷
    painter.setBrush(QColor(0, 0, 0));
    //绘制圆角矩形
    painter.drawRoundedRect(0, 0, size.width(), size.height(), 190, 190);
    //自适应图片
    QPixmap image = src.scaled(size);
    //setMask：创建不规则窗口使用
    image.setMask(mask);
    return image;
}

void PrivateChat::addMsgWidget(QWidget *widget)
{
    ui->verticalLayout->addWidget(widget);
}

void PrivateChat::mousePressEvent(QMouseEvent *event)
{
    isPressedWidget = true; // 当前鼠标按下的是QWidget而非界面上布局的其它控件
    last = event->globalPos();
}

void PrivateChat::mouseMoveEvent(QMouseEvent *event)
{
    if (isPressedWidget)
    {
        int dx = event->globalX() - last.x();
        int dy = event->globalY() - last.y();
        last = event->globalPos();
        move(x()+dx, y()+dy);
    }
}

void PrivateChat::mouseReleaseEvent(QMouseEvent *event)
{
    int dx = event->globalX() - last.x();
    int dy = event->globalY() - last.y();
    move(x()+dx, y()+dy);
    isPressedWidget = false; // 鼠标松开时，置为false
}

void PrivateChat::getPoint(QPoint& point)
{
    point = pos();
}

QWidget *PrivateChat::CreateWidgetL_R(int i, QString name, QString data)
{
    QFont font1;
    font1.setFamily("Microsoft YaHei");
    font1.setPointSize(15);
    font1.setStyleStrategy(QFont::PreferAntialias);
    QWidget * widget = new QWidget();
    widget->setStyleSheet("background:rgba(0,0,0,0);");
    widget->setMaximumWidth(700);
    QHBoxLayout *horLayout = new QHBoxLayout();//水平布局
    horLayout->setContentsMargins(0,0,0,0);
    horLayout->setSpacing(0);
    QPushButton * btnicon = new QPushButton();
    btnicon->setFixedSize(50,50);
    btnicon->setIconSize(QSize(50,50));
    btnicon->setStyleSheet("background:rgba(0,0,0,0);");
    QLabel * label = new QLabel(data);
    //内容换行处理
    int num = data.length()/45;
    for (;num>0;--num) {
        data.insert(num*45,'\n');
    }
    int count = data.count("\n");
    label->setMaximumWidth(700);
    label->setWordWrap(true);
    label->setMaximumHeight((count+2)*30);
    label->setMinimumHeight(70);
    widget->setMaximumHeight((count+4)*30);
    widget->setMinimumHeight(70);
    if(i%2)//对方消息
    {
        label->setFont(font1);
        label->setStyleSheet("background-color: rgb(140, 105, 255);border-style:solid;border-width:2px;border-color: rgb(125, 242, 255);border-radius:10px;");
        label->setTextInteractionFlags(Qt::TextSelectableByMouse);
        label->setAlignment(Qt::AlignCenter|Qt::AlignLeft);
        horLayout->addWidget(btnicon);
        horLayout->addWidget(label);
        horLayout->addStretch();
        QString headpath = OpDb::getInstance().getHeadPath(name);
        btnicon->setIcon(QPixmap(headpath));
    }
    else//我方消息
    {
        label->setFont(font1);
        label->setStyleSheet("background-color: rgb(232, 100, 150);border-style:solid;border-width:2px;border-color: rgb(100, 150, 255);border-radius:10px;");
        label->setTextInteractionFlags(Qt::TextSelectableByMouse);
        label->setAlignment(Qt::AlignCenter|Qt::AlignRight);
        horLayout->addStretch();
        horLayout->addWidget(label);
        horLayout->addWidget(btnicon);
        QString headpath = OpDb::getInstance().getHeadPath(name);
        btnicon->setIcon(QPixmap(headpath));
    }

    widget->setLayout(horLayout);
    return widget;
}

QWidget *PrivateChat::CreateWidgetL_R(int i, QString name, QPixmap pix)
{
    QWidget * widget = new QWidget();
    widget->setStyleSheet("background:rgba(0,0,0,0);");
    widget->setMinimumSize(QSize(400,300));
    widget->setMaximumSize(QSize(400,300));
    QHBoxLayout *horLayout = new QHBoxLayout();//水平布局
    horLayout->setContentsMargins(0,0,0,0);
    horLayout->setSpacing(0);
    QPushButton * btnicon = new QPushButton();
    btnicon->setFixedSize(50,50);
    btnicon->setIconSize(QSize(50,50));
    btnicon->setStyleSheet("background:rgba(0,0,0,0);");
    QLabel * label = new QLabel;
    label->setMaximumSize(QSize(400,300));
    label->setMinimumSize(QSize(400,300));
    label->setPixmap(pix);
    label->setScaledContents(true);
    if(i%2)//对方消息
    {
        horLayout->setAlignment(Qt::AlignCenter|Qt::AlignRight);
        label->setTextInteractionFlags(Qt::TextSelectableByMouse);
        label->setAlignment(Qt::AlignCenter|Qt::AlignLeft);
        horLayout->addWidget(btnicon);
        horLayout->addWidget(label);
        horLayout->addStretch();
        QString headpath = OpDb::getInstance().getHeadPath(name);
        btnicon->setIcon(QPixmap(headpath));

    }
    else//我方消息
    {
        horLayout->setAlignment(Qt::AlignCenter|Qt::AlignRight);
        //label->setTextInteractionFlags(Qt::TextSelectableByMouse);
        label->setAlignment(Qt::AlignCenter|Qt::AlignRight);
        horLayout->addStretch();
        horLayout->addWidget(label);
        horLayout->addWidget(btnicon);
        QString headpath = OpDb::getInstance().getHeadPath(name);
        btnicon->setIcon(QPixmap(headpath));
        horLayout->setAlignment(Qt::AlignCenter|Qt::AlignRight);
    }

    widget->setLayout(horLayout);

    return widget;
}



void PrivateChat::closeEvent(QCloseEvent *event)
{

}

void PrivateChat::on_btn_select_img_clicked()//选择图片
{
    m_filepath = QFileDialog::getOpenFileName(this, tr("Select an image"),
                                      ".", tr("Bitmap Files (*.bmp)\n"
                                        "JPEG (*.jpg *jpeg)\n"
                                        "GIF (*.gif)\n"
                                        "PNG (*.png)\n"));

    filepath = m_filepath;
    if(!m_filepath.isEmpty())
    {
        //获取接收人姓名
        QString recvobj = ui->recv_name->text();
        int i = recvobj.indexOf('(');
        recvobj =recvobj.replace(")","");
        recvobj = recvobj.mid(i+1);
        recvobjname = recvobj;
        qDebug()<<m_filepath<<recvobj<<endl;
        addMsgWidget(CreateWidgetL_R(0,Widget::getInstance().getName(),QPixmap(filepath)));
        //将图片发给对方
        FileTrans::getInstance().setLableContent(1,PrivateChat::getInstance().getFileName());
        emit PrivateChat::getInstance().FileTransSTart();
    }

}

void PrivateChat::on_btn_send_clicked()//发送消息
{
    if(ui->input_edit->toPlainText().size()>=1024)
    {
        QMessageBox::warning(this,"警告","消息长度不能超过1023");
        return;
    }
    if(ui->input_edit->toPlainText().isEmpty())return;
    /*文本右对齐*/
    QDateTime current_date_time = QDateTime::currentDateTime();
    QString current_date;
    current_date = Widget::getInstance().getName() +"&" + current_date_time.toString("yyyy-MM-dd hh:mm::ss");//发消息的人以及时间
    QString msg = ui->input_edit->toPlainText();
    QString name = Widget::getInstance().getName();
    ui->verticalLayout->addWidget(CreateWidgetL_R(0,name,msg));
    ui->input_edit->clear();
    //发送消息和接收人  发送人 请求类型
    PDU* pdu = makePDU(0);
    pdu->msgType=MSG_SEND;
    Widget::getInstance().getTcpSocket().write((char*)pdu,pdu->maxSize);
    userInfo u;
    QString recvobj = ui->recv_name->text();//获取接收人账号
    int i = recvobj.indexOf('(');
    recvobj =recvobj.replace(")","");
    recvobj = recvobj.mid(i+1);
    qDebug()<<recvobj<<endl;
    strcpy(u.name,recvobj.toStdString().c_str());//存放接收人
    strcpy(u.pwd,Widget::getInstance().getName().toStdString().c_str());//存放发送人
    //发送接收人和发送人
    Widget::getInstance().getTcpSocket().write((char*)&u,sizeof(u));
    //发送消息
    Widget::getInstance().getTcpSocket().write(msg.toUtf8(),msg.toUtf8().size()+1);
    //消息更新到好友列表
    MainUI::getInstance().updateFriendList(u,-2,msg);
    //每次发完消息  保存到文件
    QString filename = QString("D:\\ChatRecord\\%1-%2.txt").arg(Widget::getInstance().getName()).arg(u.name);
    QFile file(filename);
    if(!file.open(QIODevice::ReadWrite|QIODevice::Append))
    {
        QMessageBox::warning(this,"警告","创建文件失败");
        return;
    }
    current_date+="\r\n";
    file.write(current_date.toStdString().c_str());
    msg = "わ" + msg + "わ\r\n";
    file.write(msg.toStdString().c_str());
    file.close();
    delete pdu;
    pdu = nullptr;
}

void PrivateChat::on_pushButton_clicked()//选择文件发送
{
    //只能向在线的人发送文件
    QString name = ui->recv_name->text();
    if(!MainUI::getInstance().getStatus(name))
    {
        QMessageBox::information(this,"提示","对方不在线");
        return;
    }

    m_filepath = QFileDialog::getOpenFileName(this,tr("选择文件"), "C:", tr("所有文件 (*.*)\r\n图片 (*.png *.jpg *.bmp,&.jpeg)\r\n文本文件 (*.txt)"));
    filepath = m_filepath;
    if(!m_filepath.isEmpty())
    {
        //获取接收人姓名
        QString recvobj = ui->recv_name->text();
        int i = recvobj.indexOf('(');
        recvobj =recvobj.replace(")","");
        recvobj = recvobj.mid(i+1);
        recvobjname = recvobj;
        qDebug()<<m_filepath<<recvobj<<endl;
        userInfo u;
        strcpy(u.name,recvobj.toStdString().c_str());//存放接收人
        strcpy(u.pwd,Widget::getInstance().getName().toStdString().c_str());//存放发送人
        PDU* pdu = makePDU(0);
        pdu->msgType = FILE_REQUEST;
        Widget::getInstance().getTcpSocket().write((char*)pdu,pdu->maxSize);
        Widget::getInstance().getTcpSocket().write((char*)&u,sizeof (u));
        //Widget::getInstance().getTcpSocket().write(m_filepath.toUtf8(),m_filepath.toUtf8().length()+1);

        FileTrans::getInstance().setLableContent(0,"");
        FileTrans::getInstance().show();
        delete pdu;
        pdu = nullptr;
    }
}

void PrivateChat::on_friend_list_itemClicked(QListWidgetItem *item)//点击了聊天联系人
{
    QList<PrivateChat*> list = Widget::getInstance().getPrivateChatList();
    for(auto x:list)
    {
        if(x->getObjName()==item->text())
            x->show();
        else
            x->hide();
    }
}

void PrivateChat::ColoringListItem()
{
    if(m_prevItem!=nullptr && m_prevItem->text()!=ui->recv_name->text())
    {
        m_prevItem->setBackground(QBrush(QColor(255,255,255)));
    }
    QString text = ui->recv_name->text();
    QList<QListWidgetItem*> list = ui->friend_list->findItems(text,Qt::MatchContains);
    if(list.size()!=0)
    {
        list[0]->setBackground(QBrush(QColor(150,150,150)));
        m_prevItem = list[0];
    }
}

void PrivateChat::OnFileTransSTart()
{
    //获取接收人姓名
    qDebug()<<filepath<<recvobjname<<endl;
    userInfo u;
    strcpy(u.name,recvobjname.toStdString().c_str());//存放接收人
    strcpy(u.pwd,Widget::getInstance().getName().toStdString().c_str());//存放发送人

    QFileInfo innfo(filepath);
    QString str = QString("%1&%2").arg(innfo.fileName()).arg(innfo.size());
    QString Info = QString("%1&%2&%3").arg(u.name).arg(u.pwd).arg(str);
    //发送 接收人和发送人 文件信息
    int r =  Widget::getInstance().getFileSocket().write(Info.toUtf8(),Info.toUtf8().length()+1);//发送文件信息

    if(r>0)//发送信息成功后
    {
        filesize = innfo.size();
        filename = innfo.fileName();
        sendsize = 0;
        m_file.setFileName(filepath);
        if(!m_file.open(QIODevice::ReadOnly))
        {
            QMessageBox::warning(this,"","打开文件失败");
            return;
        }
        FileTrans::getInstance().setProgressMax(filesize);
        m_filetimer.start(20);
    }
}


void PrivateChat::on_toolButton_clicked()
{
    hide();
}

void PrivateChat::on_toolButton_2_clicked()
{
    hide();
}

void PrivateChat::on_tbtn_lookinfo_clicked()//查看个人资料
{
    QString str = ui->recv_name->text();
    int i = str.indexOf('(');
    str =str.replace(")","");
    str = str.mid(i+1);
    PersonInfoUI* pui = new PersonInfoUI(nullptr);
    pui->initUserInfo(str);
    pui->hideEditInofoBtn();
    pui->show();
}

void PrivateChat::on_tbtn_doudong_clicked()//发送抖动
{
    //只能向在线的人发送抖动请求
    QString test = ui->recv_name->text();
    if(!MainUI::getInstance().getStatus(test))
    {
        QMessageBox::information(this,"提示","对方不在线");
        return;
    }

    PDU* pdu = makePDU(0);
    //发送消息和接收人  发送人 请求类型
    pdu->msgType = SEND_MOVE;
    Widget::getInstance().getTcpSocket().write((char*)pdu,pdu->maxSize);
    userInfo u;
    QString recvobj = ui->recv_name->text();//获取接收人账号
    int i = recvobj.indexOf('(');
    recvobj =recvobj.replace(")","");
    recvobj = recvobj.mid(i+1);
    qDebug()<<recvobj<<endl;
    strcpy(u.name,recvobj.toStdString().c_str());//存放接收人
    strcpy(u.pwd,Widget::getInstance().getName().toStdString().c_str());//存放发送人
    //发送接收人和发送人
    Widget::getInstance().getTcpSocket().write((char*)&u,sizeof(u));
    delete pdu;
    pdu = nullptr;
}

void PrivateChat::on_tbtn_biaoqing_clicked()
{
    ExpressionUI& eui = ExpressionUI::getInstance();
    eui.show();
    connect(&eui,&ExpressionUI::Expre,[=](QString str){

    });
}

void PrivateChat::on_tbtn_jietu_clicked()//截图
{
    QProcess pro(this);
    pro.startDetached(QString("D:\\QTCode5.14\\CClient\\release\\截图.exe"));
}

void PrivateChat::on_tbtn_media_clicked()
{
    //只能向在线的人发送视频请求
    QString test = ui->recv_name->text();
    if(!MainUI::getInstance().getStatus(test))
    {
        QMessageBox::information(this,"提示","对方不在线");
        return;
    }

    QString recvobj = ui->recv_name->text();//获取接收人账号
    QString name = Widget::getInstance().getName();//获取发送人账户
    int i = recvobj.indexOf('(');
    recvobj =recvobj.replace(")","");
    recvobj = recvobj.mid(i+1);
    PDU* pdu = makePDU(0);
    pdu->msgType = MEDIA_REQUEST;
    Widget::getInstance().getTcpSocket().write((char*)pdu,pdu->maxSize);
    userInfo u;
    memset(&u,0,sizeof (u));
    strcpy(u.name,recvobj.toStdString().c_str());//存放接收人
    strcpy(u.pwd,name.toStdString().c_str());//存放发送人
    Widget::getInstance().getTcpSocket().write((char*)&u,sizeof (u));
    ui->verticalLayout->addWidget(CreateWidgetL_R(0,name,"等待对方接受视频请求......"));
    delete pdu;
    pdu = nullptr;
}
